package thread;

/**
 * 演示多线程并发安全问题:
 * 当多个线程操作同一临界资源，由于线程切换时机不确定，导致执行顺序出现混乱，从而产生不良后果。
 * 这种线程称为多线程并发安全问题
 *
 * 以银行取钱为例，模拟两个人同时从同一个账号上取款
 */
public class Bank {
    private int account = 20000;//某账号的余额
    /*
        当一个方法被synchronized修饰，该方法称为"同步方法"，同步要求要求多个线程不能
        同时在方法内部执行。
        将多个线程并发操作临界资源改为同步(有先后顺序)的执行就可以有效的解决并发安全问题
        大白话:将多个线程抢着执行变成排队执行
     */
    //取钱方法，参数:要取出钱款的金额
    public synchronized boolean getMoney(int money){
        //获取账号余额
        int account = getAccount();
        //判断余额是否足够
        if(account>=money){//余额>=要取的钱
            account = account-money;//计算新余额
            Thread.yield();//主动放弃当前线程本次时间片，模拟执行到这里没有时间发生线程切换
            saveAccount(account);//重新记账
            return true;//允许出钞
        }
        return false;//余额不足则拒绝出钞
    }
    //记账
    public void saveAccount(int account){
        this.account = account;
    }

    //获取账号余额
    public int getAccount(){
        return account;
    }

}







